#pragma once
#include <iostream>
#include <string>
#include <cstdlib>
#include <pthread.h>
#include <functional>


// demo线程的封装
class Thread
{
public:
    typedef enum
    {
        NEW = 0,
        RUNNING,
        EXITED
    } ThreadStatus;
    // typedef void (*func_t)(void*); // 函数指针
    using func_t = std::function<void ()>;

public:
    Thread(int num, func_t func)
        : _tid(0), _status(NEW), _func(func)
    {
        char name[128];
        snprintf(name, sizeof(name), "thread--%d", num);
        _name = name;
    }

    int status()
    {
        return _status; // 获取线程状态
    }

    std::string threadname()
    {
        return _name; // 获取线程名字
    }

    pthread_t threadid()
    {
        if (_status == RUNNING)
            return _tid; // 获取线程id
        else
        {
            // std::cout<<"thread is not running, no tid"<<std::endl;
            return 0;
        }
    }

    // 此时的runHelper是不是类的成员函数，而类的成员函数，具有默认参数this，而runHelper的默认参数是void*的
    //  void *runHelper(void *args)
    //  {
    //  }
    // 此时需要static，
    // 但是会有新问题:static成员函数，无法直接访问类属性和其他成员函数，所以创建线程要传this
    static void *runHelper(void *args)
    {
        Thread *ts = (Thread *)args; // 就拿到了当前对象
        //_func(_args);
        (*ts)();
        return nullptr;
    }

    void operator()() // 仿函数
    {
        if (_func != nullptr) // 回调函数不为空，成功
            _func();     // 回调一下函数
    }

    void run()
    {
        int n = pthread_create(&_tid, nullptr, runHelper, this /*nullptr*/);
        if (n != 0)
            exit(1);
        _status = RUNNING;
    }

    void join()
    {
        int n = pthread_join(_tid, nullptr);
        if (n != 0)
        {
            std::cerr << "main thread join thread" << _name << " error" << std::endl;
            return;
        }
        _status = EXITED;
    }

    ~Thread()
    {
    }

private:
    pthread_t _tid;
    std::string _name;
    func_t _func; // 线程未来要执行的回调
    // void *_args;
    ThreadStatus _status;
};